package cn.school.dashboard.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.school.classManage.dao.SchoolClassDao;
import cn.school.classManage.service.SchoolClassService;
import cn.school.classManage.vo.SchoolClassVO;
import cn.school.common.utils.StringUtils;
import cn.school.common.utils.SysUserUtils;
import cn.school.dashboard.service.CampusDashBoardService;
import cn.school.dashboard.vo.*;
import cn.school.notice.dao.SchoolNoticeDao;
import cn.school.notice.entity.SchoolNotice;
import cn.school.student.dao.StudentInfoDao;
import cn.school.student.entity.StudentInfo;
import cn.school.workflow.dao.LeaveApplyDao;
import cn.school.workflow.dao.StudentLeaveSelfApplyDao;
import cn.school.workflow.vo.LeaveApplyVO;
import cn.school.workflow.vo.StudentLeaveSelfApplyVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @className: CampusDashBoardServiceImpl
 * @author: Alex
 * @date: 2023/4/18
 **/
@Service
public class CampusDashBoardServiceImpl implements CampusDashBoardService {
	private static final String[] MONTHS = new String[] {"一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"};
	
	@Resource
	private SchoolNoticeDao schoolNoticeDao;
	
	@Resource
	private LeaveApplyDao leaveApplyDao;
	
	@Resource
	private SchoolClassDao schoolClassDao;
	
	@Resource
	private StudentInfoDao studentInfoDao;
	
	@Resource
	private StudentLeaveSelfApplyDao studentLeaveSelfApplyDao;
	
	@Autowired
	private SchoolClassService schoolClassService;
	
	@Override
	public List<NoticeTypeBoard> getSchoolNoticeList() {
		LambdaQueryWrapper<SchoolNotice> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(SchoolNotice::getTenantId, SysUserUtils.getSysUser().getTenantId());
		List<SchoolNotice> schoolNotices = schoolNoticeDao.selectList(queryWrapper);
		List<NoticeTypeBoard> collect = Stream.of(new NoticeTypeBoard("0", "学工通知", 0),
						new NoticeTypeBoard("1", "违纪通知", 0),
						new NoticeTypeBoard("2", "安全通知", 0))
				.collect(Collectors.toList());
		
		for (NoticeTypeBoard noticeTypeBoard : collect) {
			List<SchoolNotice> notices = schoolNotices.stream().filter(schoolNotice -> Objects.equals(schoolNotice.getNoticeType(), noticeTypeBoard.getNoticeType())).collect(Collectors.toList());
			noticeTypeBoard.setNoticeCount(notices.size());
		}
		return collect;
	}
	
	@Override
	public List<TeacherLeaveVo> getTeacherLeaveList() {
		LambdaQueryWrapper<LeaveApplyVO> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(LeaveApplyVO::getTenantId, SysUserUtils.getSysUser().getTenantId());
		List<LeaveApplyVO> applyVOS = leaveApplyDao.selectList(queryWrapper);
		List<TeacherLeaveVo> collect = Stream.of(new TeacherLeaveVo("1", "事假", "0%"),
				new TeacherLeaveVo("2", "病假", "0%"),
				new TeacherLeaveVo("3", "婚假", "0%"),
				new TeacherLeaveVo("4", "年假", "0%")
		).collect(Collectors.toList());
		
		for (TeacherLeaveVo teacherLeaveVo : collect) {
			DecimalFormat df = new DecimalFormat("##%");
			List<LeaveApplyVO> vos = applyVOS.stream().filter(leaveApplyVO -> StringUtils.equals(teacherLeaveVo.getLeaveType(), leaveApplyVO.getLeaveType())).collect(Collectors.toList());
			teacherLeaveVo.setTypeRatio(df.format((double) vos.size() / applyVOS.size()));
		}
		
		return collect;
	}
	
	@Override
	public List<Map<String, String>> getClassStudentList() {
		SchoolClassVO vo = new SchoolClassVO();
		vo.setPageNum(1);
		vo.setPageSize(10000);
		vo.setClassTeacherId(SysUserUtils.getSysUser().getUsername());
		vo.setLoginUserId(SysUserUtils.getSysUser().getId());
		List<SchoolClassVO> records = schoolClassService.findSchoolClassPageList(vo).getRecords();
		List<Map<String, String>> resultList = new ArrayList<>();
		for (SchoolClassVO record : records) {
			Map<String, String> resultMap = new HashMap<>();
			resultMap.put(record.getClassName(), String.valueOf(record.getPersonCount()));
			resultList.add(resultMap);
		}
		return resultList;
	}
	
	@Override
	public List<SchoolPositionVo> getSchoolDistribution() {
		List<SchoolPositionVo> collect = Stream.of(new SchoolPositionVo("104.08169", "30.58033", "成都校区"),
				new SchoolPositionVo("113.10057", "29.26016", "岳阳校区"),
				new SchoolPositionVo("113.05516", "28.22203", "长沙校区"),
				new SchoolPositionVo("114.25232", "30.61732", "武汉校区"),
				new SchoolPositionVo("116.49337", "39.87258", "北京校区"),
				new SchoolPositionVo("113.31240", "23.13753", "广州校区")).collect(Collectors.toList());
		return collect;
	}
	
	@Override
	public List<ClassLeaveRankVo> getClassLeaveRanking() {
		List<ClassLeaveRankVo> rankVos = new ArrayList<>();
		// 查询出所有的班级
		LambdaQueryWrapper<SchoolClassVO> classQueryWrapper = new LambdaQueryWrapper<>();
		classQueryWrapper.eq(SchoolClassVO::getTenantId, SysUserUtils.getSysUser().getTenantId());
		List<SchoolClassVO> classVOS = schoolClassDao.selectList(classQueryWrapper);
		
		// 构造当前年的数据
		getClassLeaveDataByDateType(rankVos, classVOS, "currentYear");
		
		// 构造本月的数据
		getClassLeaveDataByDateType(rankVos, classVOS, "currentMonth");
		
		// 构造当天的数据
		getClassLeaveDataByDateType(rankVos, classVOS, "currentDay");
		
		return rankVos;
	}
	
	@Override
	public List<AddedStudentVo> getAddedStudentList() {
		Date currentDate = new Date();
		String year = DateUtil.format(currentDate, "yyyy");  // 当前年
		String lastYear = String.valueOf(Integer.parseInt(year) - 1); // 前一年
		List<AddedStudentVo> addedStudentVos = new ArrayList<>();
		getMonthDataList(year, addedStudentVos);
		getMonthDataList(lastYear, addedStudentVos);
		return addedStudentVos;
	}
	
	private void getMonthDataList(String year, List<AddedStudentVo> addedStudentVos) {
		// 查询出当前年的数据
		LambdaQueryWrapper<StudentInfo> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.like(StudentInfo::getEntranceDate, year);
		queryWrapper.eq(StudentInfo::getTenantId, SysUserUtils.getSysUser().getTenantId());
		List<StudentInfo> studentInfos = studentInfoDao.selectList(queryWrapper);
		
		AddedStudentVo vo = new AddedStudentVo();
		vo.setYearName(year);
		List<Map<String, String>> months = new ArrayList<>();
		for (int i = 0; i < MONTHS.length; i++ ) {
			String month = MONTHS[i];
			Map<String, String> map = new HashMap<>();
			int finalI = i;
			List<StudentInfo> collect = studentInfos.stream().filter(studentInfo -> {
				String entranceDate = studentInfo.getEntranceDate();
				DateTime parse = DateUtil.parse(entranceDate, "yyyy-MM");
				return DateUtil.month(parse) == finalI;  // month方法获取月份从0开始
			}).collect(Collectors.toList());
			map.put(month, String.valueOf(collect.size()));
			months.add(map);
		}
		vo.setMonthData(months);
		addedStudentVos.add(vo);
	}
	
	private void getClassLeaveDataByDateType(List<ClassLeaveRankVo> rankVos, List<SchoolClassVO> classVOS, String dateType) {
		Date currentDate = new Date();
		
		List<Long> classIds = classVOS.stream().map(SchoolClassVO::getId).collect(Collectors.toList());
		// 根据班级id查询请假信息
		LambdaQueryWrapper<StudentLeaveSelfApplyVO> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.in(StudentLeaveSelfApplyVO::getClassId, classIds);
		// 查询所有数据
		DateTime dateTime  = DateUtil.beginOfDay(currentDate);
		if (StringUtils.equals(dateType, "currentYear")) {
			dateTime = DateUtil.offsetWeek(currentDate, -12);
		}
		if (StringUtils.equals(dateType, "currentMonth")) {
			dateTime = DateUtil.offsetWeek(currentDate, -1);
		}
		queryWrapper.gt(StudentLeaveSelfApplyVO::getCreateTime, dateTime);
		queryWrapper.eq(StudentLeaveSelfApplyVO::getTenantId, SysUserUtils.getSysUser().getTenantId());
		List<StudentLeaveSelfApplyVO> selfApplyVOS = studentLeaveSelfApplyDao.selectList(queryWrapper);
		
		Map<String, List<StudentLeaveSelfApplyVO>> collect = selfApplyVOS.stream().collect(Collectors.groupingBy(StudentLeaveSelfApplyVO::getClassId));
		
		ClassLeaveRankVo rankVo = new ClassLeaveRankVo();
		List<Map<String, String>> yearClassRank = new ArrayList<>();
		for (SchoolClassVO classVO : classVOS) {
			Map<String, String> classMap = new HashMap<>();
			List<StudentLeaveSelfApplyVO> vos = collect.get(String.valueOf(classVO.getId()));
			classMap.put(classVO.getClassName(), vos != null ? String.valueOf(vos.size()) : "0");
			yearClassRank.add(classMap);
		}
		rankVo.setDateType(dateType);
		rankVo.setClassData(yearClassRank);
		rankVos.add(rankVo);
	}
}
